iT邦幫忙

2024 iThome 鐵人賽

DAY 5
1
Software Development

Rust 學得動嗎系列 第 5

[Day 5] Rust 生命週期:確保引用有效性的關鍵

  • 分享至 

  • xImage
  •  

今天,我們來看 Rust 的生命週期(Lifetime)概念。生命週期是 Rust 借用檢查器用來確保所有借用都是有效的機制,它與所有權系統密切相關。

什麼是生命週期?

生命週期是 Rust 編譯器用來確保所有的引用在被使用時都是有效的。它告訴編譯器不同引用的有效範圍,以防止懸垂指針的產生。

生命週期標註語法

生命週期參數的名稱以撇號(')開頭,通常使用小寫字母,如 'a:

&i32        // 一個引用
&'a i32     // 具有顯式生命週期的引用
&'a mut i32 // 具有顯式生命週期的可變引用

函數中的生命週期

當函數返回一個引用時,其生命週期必須與某個輸入參數的生命週期相關:

fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

這個函數聲明了一個泛型生命週期 'a,並用它標註了兩個參數和返回值。

結構體中的生命週期

當結構體包含引用時,我們需要為每個引用標註生命週期:

struct Excerpt<'a> {
    part: &'a str,
}

這表示 Excerpt 實例的生命週期不能超過 part 字段引用的字串切片。

生命週期省略規則

Rust 有一些生命週期省略規則,在某些常見模式下允許我們省略顯式的生命週期標註:

  1. 每個引用參數都有自己的生命週期參數。
  2. 如果只有一個輸入生命週期參數,那麼它被賦予所有輸出生命週期參數。
  3. 如果有多個輸入生命週期參數,但其中一個是 &self 或 &mut self,那麼 self 的生命週期被賦予所有輸出生命週期參數。

靜態生命週期

'static 是一個特殊的生命週期,它存活於整個程序運行期間:

let s: &'static str = "I have a static lifetime.";

生命週期約束

我們可以使用生命週期參數來限制泛型類型:

use std::fmt::Display;

fn longest_with_an_announcement<'a, T>(
    x: &'a str,
    y: &'a str,
    ann: T,
) -> &'a str
where
    T: Display,
{
    println!("Announcement! {}", ann);
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

實際應用例子

讓我們看一個更複雜的範例,展示生命週期在實際程式中的應用:

struct Config<'a> {
    host: &'a str,
    port: u16,
}

struct Client<'a> {
    config: &'a Config<'a>,
}

impl<'a> Client<'a> {
    fn new(config: &'a Config) -> Client<'a> {
        Client { config }
    }

    fn get_host(&self) -> &'a str {
        self.config.host
    }
}

fn main() {
    let config = Config {
        host: "localhost",
        port: 8080,
    };
    let client = Client::new(&config);
    println!("Connected to: {}", client.get_host());
}

上一篇
[Day 4] Rust 的核心:深入理解所有權系統
下一篇
[Day 6] Rust 的錯誤處理:優雅地管理失敗
系列文
Rust 學得動嗎30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言